package sk.stuba.fiit.clientApp.gui.handler;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.cert.CRLException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.Date;

import javax.swing.JOptionPane;

import org.bouncycastle.tsp.TSPException;
import org.bouncycastle.tsp.TimeStampResponse;

import sk.stuba.fiit.clientApp.controller.ClientUtil;
import sk.stuba.fiit.clientApp.cvo.CertificateCVO;
import sk.stuba.fiit.clientApp.cvo.CrlCVO;
import sk.stuba.fiit.clientApp.gui.panel.BasicPanel;
import sk.stuba.fiit.clientApp.singeltons.ControllerLocatorSingelton;
import sk.stuba.fiit.clientApp.util.Util;
import sun.security.x509.X509CRLImpl;

public class PreferenceExecuteActionListener  implements ActionListener{
	BasicPanel panel ;

	public PreferenceExecuteActionListener(BasicPanel basicPanel) {
		this.panel = basicPanel;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String value = (String) panel.getComboBoxPreference().getModel()
				.getSelectedItem();
		ControllerLocatorSingelton application = ControllerLocatorSingelton
				.getInstance();
		switch(value.charAt(0)){
		case '1':
				if(panel.getTfPreferencies().getText().equals("")){
					JOptionPane.showMessageDialog(null,"Data must be selected!", "Error",JOptionPane.ERROR_MESSAGE);
					return;
				}
			try {
				File file = new File(panel.getTfPreferencies().getText());
				TimeStampResponse tsr = application.getSignatureContreoller().getTimeStamp(file, ClientUtil.getASN1ObjIdFromString("SHA-1"), "SHA1");
				File output = new File(file.getName()+".ts");
				FileOutputStream fos = new FileOutputStream(output);
				fos.write(tsr.getEncoded());
				fos.close();
				panel.getConsole().append(new Date()+ "\t\tTime stamp was saved to output: "+output.getAbsolutePath()+"\n");
			} catch (IOException e1) {
				JOptionPane.showMessageDialog(null, "Error durin retrieving timestamp for data", "Error", JOptionPane.ERROR_MESSAGE);
			}
			break;
		case '2':
			try{
			String serialNum = panel.getTfPreferencies().getText();
			CertificateCVO response = application.getSignatureContreoller().getCertificate(serialNum);
			panel.getConsolePref().setText(response.getCertificate().toString());
			panel.getConsole().append(new Date()+ "\t\tCRL was obtain and saved to output: "+response.getOutput()+"\n");
			}catch(Exception e1){
				e1.printStackTrace();
			}
			
			break;
		case '3':
			try {
				CrlCVO crl = application.getSignatureContreoller().getCRL();
				panel.getConsolePref().setText(crl.getCrl().toString());
				panel.getConsole().append(new Date()+ "\t\tCRL was obtain and saved to output: "+crl.getOutput()+"\n");
			} catch (Exception e4) {
				e4.printStackTrace();
				JOptionPane.showMessageDialog(null, "Error durin retrieving crl for CA", "Error", JOptionPane.ERROR_MESSAGE);
			}
			break;
		case '4':
			if(panel.getTfPreferencies().getText().equals("")){
				JOptionPane.showMessageDialog(null,"Time stamp location must be selected!", "Error",JOptionPane.ERROR_MESSAGE);
				return;
			}
			try {
				File file = new File(panel.getTfPreferencies().getText());
				FileInputStream fis = new FileInputStream(file);
				byte [] data = new byte[(int) file.length()];
				fis.read(data);
				fis.close();
				TimeStampResponse tsr = new TimeStampResponse(data);
				StringBuilder sb = new StringBuilder();
				sb.append("Status: "); sb.append(tsr.getStatusString()).append("\n");
				sb.append("Time: "); sb.append(tsr.getTimeStampToken().getTimeStampInfo().getGenTime()).append("\n");
				sb.append("Hash algorithm: ").append(tsr.getTimeStampToken().getTimeStampInfo().getHashAlgorithm().getAlgorithm()).append("\n");
				sb.append("Message digest: ").append(Util.codeByteToBase64String(tsr.getTimeStampToken().getTimeStampInfo().getMessageImprintDigest())).append("\n");
				
				panel.getConsolePref().setText(sb.toString());
				
				System.out.println(tsr);
			} catch (FileNotFoundException e1) {
				JOptionPane.showMessageDialog(null, "File not found!", "Error", JOptionPane.ERROR_MESSAGE);
			} catch (IOException e2) {
				JOptionPane.showMessageDialog(null, "Can not read from file!", "Error", JOptionPane.ERROR_MESSAGE);
				e2.printStackTrace();
			} catch (TSPException e3) {
				JOptionPane.showMessageDialog(null, "Wrong file format!", "Error", JOptionPane.ERROR_MESSAGE);
				e3.printStackTrace();
			}
			break;
		case '5':
			if(panel.getTfPreferencies().getText().equals("")){
				JOptionPane.showMessageDialog(null,"Certificate location must be selected!", "Error",JOptionPane.ERROR_MESSAGE);
				return;
			}
			try {
			File file = new File(panel.getTfPreferencies().getText());
			FileInputStream fis = new FileInputStream(file);
			byte [] data = new byte[(int) file.length()];
			fis.read(data);
			fis.close();
			CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
			InputStream in = new ByteArrayInputStream(data);		
			X509Certificate certificate = (X509Certificate)certFactory.generateCertificate(in);
			panel.getConsolePref().setText(certificate.toString());

			} catch (IOException e1) {
				JOptionPane.showMessageDialog(null, "Can not read from file!", "Error", JOptionPane.ERROR_MESSAGE);
				e1.printStackTrace();
			} catch (CertificateException e2) {
				JOptionPane.showMessageDialog(null, "Wrong file format!", "Error", JOptionPane.ERROR_MESSAGE);
				e2.printStackTrace();
			}

			break;
		case '6':
			if(panel.getTfPreferencies().getText().equals("")){
				JOptionPane.showMessageDialog(null,"Certificate location must be selected!", "Error",JOptionPane.ERROR_MESSAGE);
				return;
			}
			
			try {
			File file = new File(panel.getTfPreferencies().getText());
			FileInputStream fis;
				fis = new FileInputStream(file);
			
			byte [] data = new byte[(int) file.length()];
			fis.read(data);
			fis.close();
			X509CRL crl = new X509CRLImpl(data);
			panel.getConsolePref().setText(crl.toString());
			} catch (Exception e1) {
				JOptionPane.showMessageDialog(null, "Can not read from file or wrong file format!", "Error", JOptionPane.ERROR_MESSAGE);
				e1.printStackTrace();
			}
			break;
		}
		
	}
}
